package com.wlsmartlock.BleUnit;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;

import com.wlsmartlock.Utils.App;
import com.wlsmartlock.Utils.ByteUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import static android.support.constraint.Constraints.TAG;

public class BleService extends Service {
    private final static String TAG = BleService.class.getSimpleName();
    public static BluetoothGatt mBluetoothGatt;
    // 蓝牙连接状态
    private int mConnectionState = 0;
    // 蓝牙连接已断开
    private final int STATE_DISCONNECTED = 0;
    // 蓝牙正在连接
    private final int STATE_CONNECTING = 1;
    // 蓝牙已连接
    private final int STATE_CONNECTED = 2;


    private final static String Key_Password = ByteUtils.byteArrayToHexString("HZWL-prevail".getBytes());

    // 蓝牙已连接
    public final static String ACTION_GATT_CONNECTED = "com.long.ble.ACTION_GATT_CONNECTED";
    // 蓝牙已断开
    public final static String ACTION_GATT_DISCONNECTED = "com.long.ble.ACTION_GATT_DISCONNECTED";
    // 发现GATT服务
    public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.long.ble.ACTION_GATT_SERVICES_DISCOVERED";
    // 收到蓝牙数据
    public final static String ACTION_DATA_AVAILABLE = "com.long.ble.ACTION_DATA_AVAILABLE";
    // 连接失败
    public final static String ACTION_CONNECTING_FAIL = "com.long.ble.ACTION_CONNECTING_FAIL";
    // 蓝牙数据
    public final static String EXTRA_DATA = "com.long.ble.EXTRA_DATA";

    // 服务标识
    public final static UUID SERVICE_UUID = UUID.fromString("6e400001-b5a3-f393-e0a9-e50e24dcca9e");
    // 特征标识（读取数据）
    private final UUID CHARACTERISTIC_READ_UUID = UUID.fromString("6e400003-b5a3-f393-e0a9-e50e24dcca9e");
    // 特征标识（发送数据）
    private final static UUID CHARACTERISTIC_WRITE_UUID = UUID.fromString("6e400002-b5a3-f393-e0a9-e50e24dcca9e");
    // 描述标识
    private final UUID DESCRIPTOR_UUID = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

    // 服务相关
    private final IBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        public BleService getService() {
            return BleService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        release();
        return super.onUnbind(intent);
    }

    /**
     * 蓝牙操作回调
     * 蓝牙连接状态才会回调
     */
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                // 蓝牙已连接
                mConnectionState = STATE_CONNECTED;
                App.mConnectionState = STATE_CONNECTED;

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 搜索GATT服务
                mBluetoothGatt.discoverServices();
                sendBleBroadcast(ACTION_GATT_CONNECTED);

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                // 蓝牙已断开连接
                mConnectionState = STATE_DISCONNECTED;
                App.mConnectionState = STATE_DISCONNECTED;
                sendBleBroadcast(ACTION_GATT_DISCONNECTED);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            // 发现GATT服务
            if (status == BluetoothGatt.GATT_SUCCESS) {

                setBleNotification();
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            // 收到数据
            sendBleBroadcast(ACTION_DATA_AVAILABLE, characteristic);
        }
    };

    /**
     * 发送通知
     *
     * @param action 广播Action
     */
    private void sendBleBroadcast(String action) {
        Intent intent = new Intent(action);
        sendBroadcast(intent);
    }

    /**
     * 发送通知
     *
     * @param action         广播Action
     * @param characteristic 数据
     */
    private void sendBleBroadcast(String action, BluetoothGattCharacteristic characteristic) {
        Intent intent = new Intent(action);
        if (CHARACTERISTIC_READ_UUID.equals(characteristic.getUuid())) {
            intent.putExtra(EXTRA_DATA, characteristic.getValue());
        }
        sendBroadcast(intent);
    }

    /**
     * 蓝牙连接
     *
     * @param bluetoothAdapter BluetoothAdapter
     * @param address          设备mac地址
     * @return true：成功 false：
     */
    public boolean connect(BluetoothAdapter bluetoothAdapter, String address) {
        if (bluetoothAdapter == null || TextUtils.isEmpty(address)) {
            return false;
        }

        BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            return false;
        }
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        mConnectionState = STATE_CONNECTING;
        App.mConnectionState = STATE_CONNECTING;
        return true;
    }

    /**
     * 蓝牙断开连接
     */
    public void disconnect() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.disconnect();
    }

    /**
     * 释放相关资源
     */
    public void release() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
    }

    /**
     * 设置蓝牙设备在数据改变时，通知App
     */
    public void setBleNotification() {
        if (mBluetoothGatt == null) {
            sendBleBroadcast(ACTION_CONNECTING_FAIL);
            return;
        }

        // 获取蓝牙设备的服务
        BluetoothGattService gattService = mBluetoothGatt.getService(SERVICE_UUID);
        if (gattService == null) {
            sendBleBroadcast(ACTION_CONNECTING_FAIL);
            return;
        }

        // 获取蓝牙设备的特征
        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(CHARACTERISTIC_READ_UUID);
        if (gattCharacteristic == null) {
            sendBleBroadcast(ACTION_CONNECTING_FAIL);
            return;
        }

        // 获取蓝牙设备特征的描述符
        BluetoothGattDescriptor descriptor = gattCharacteristic.getDescriptor(DESCRIPTOR_UUID);
        if(descriptor != null){
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            if (mBluetoothGatt.writeDescriptor(descriptor)) {
                // 蓝牙设备在数据改变时，通知App，App在收到数据后回调onCharacteristicChanged方法
                mBluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
            }
        }

    }

    /**
     * 发送数据
     *
     * @param data 数据
     * @return true：发送成功 false：发送失败
     */
    public static boolean sendData(int cmd,String data) {
        // 获取蓝牙设备的服务
        BluetoothGattService gattService = null;
        if (mBluetoothGatt != null) {
            gattService = mBluetoothGatt.getService(SERVICE_UUID);
        }
        //循环3次获取Service
        for(int i = 0; i < 5; i++){
            if (gattService == null) {
                try {
                    Thread.sleep(100);
                    gattService = mBluetoothGatt.getService(SERVICE_UUID);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                break;
            }
        }
        if (gattService == null) {
            return false;
        }

        // 获取蓝牙设备的特征
        BluetoothGattCharacteristic gattCharacteristic = gattService.getCharacteristic(CHARACTERISTIC_WRITE_UUID);
        for(int i = 0; i < 5; i++){
            if (gattCharacteristic == null) {
                Log.i(TAG, "获取gattCharacteristic失败" );
                try {
                    Thread.sleep(100);
                    gattCharacteristic = gattService.getCharacteristic(CHARACTERISTIC_WRITE_UUID);
                } catch (InterruptedException e) {
                    Log.i(TAG, "获取gattCharacteristic失败" );
                }
            }else{
                break;
            }
        }
        if (gattCharacteristic == null) {
            return false;
        }
        //组装数据
        int len = 0;
        if(cmd == 0xc5){
            len = 19;
        }else if(cmd == 0xc4){
            len = data.length() + 7;
        }else if(cmd == 0xc3){
            len = 8;
        }else{
            len = data.length()/2 + 7;
        }
        byte[] sdd = new byte[len];
        byte[] sd;
        sdd[0] = (byte)0xa0;
        sdd[1] = (byte)0xb0;

        switch(cmd){
            case 0xc4:
                sdd[2] = (byte)0xc4;
                sdd[3] = (byte)0x00;
                sdd[4] = (byte)0x10;
                sd = data.getBytes();

                System.arraycopy(sd,0,sdd,5,sd.length);
                break;
            case 0xc5:
                sdd[2] = (byte)0xc5;
                sdd[3] = (byte)0x00;
                sdd[4] = (byte)0x0e;
                sd = ByteUtils.hexStr2Byte(Key_Password);

                System.arraycopy(sd,0,sdd,5,sd.length);

                break;
            case 0xc6:
                sdd[2] = (byte)0xc6;
                sdd[3] = (byte)0x00;
                sdd[4] = (byte)0x02;

                break;
            case 0xc2:
                sdd[2] = (byte)0xc2;
                byte[] len1 = ByteUtils.itobytes(len - 5);
                sdd[3] = len1[2];
                sdd[4] = len1[3];
                sd = ByteUtils.hexStr2Byte(data);
                System.arraycopy(sd,0,sdd,5,sd.length);
                break;
            case 0xc3:
                sdd[2] = (byte)0xc3;
                sdd[3] = (byte)0x00;
                sdd[4] = (byte)0x03;
                if(data == "1"){
                    sdd[5] = (byte)0x01;
                }else{
                    sdd[5] = (byte)0x00;
                }
                break;
            default:
                break;
        }
        //计算校验和
        byte[] crc = sum_crc(sdd);
        sdd[sdd.length - 1] = crc[7];
        sdd[sdd.length - 2] = crc[6];

        Log.i(TAG, "sendData: " + ByteUtils.byteArrayToHexString(sdd));
        // 发送数据
        gattCharacteristic.setValue(sdd);
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return mBluetoothGatt.writeCharacteristic(gattCharacteristic);
    }

    public static byte[] sum_crc(byte[] data){
        long sum = 0;
        for(int i = 2; i < data.length; i++){
            sum += (long)data[i] >= 0?(long)data[i]:((long)data[i] + 256);
        }

        return ByteUtils.longToBytes(~sum);
    }

}
